using Microsoft.Extensions.Logging;
using SeataNet.Core.AT.UndoLog;
using System.Collections.Concurrent;
using System.Data.Common;

namespace SeataNet.Core.Database
{
    /// <summary>
    /// 表元数据缓存默认实现
    /// </summary>
    public class DefaultTableMetaCache : ITableMetaCache
    {
        private readonly ILogger<DefaultTableMetaCache> _logger;
        private readonly IDatabaseDialect _dialect;
        private readonly ConcurrentDictionary<string, TableMeta> _cache;

        public DefaultTableMetaCache(
            ILogger<DefaultTableMetaCache> logger,
            IDatabaseDialect dialect)
        {
            _logger = logger;
            _dialect = dialect;
            _cache = new ConcurrentDictionary<string, TableMeta>(StringComparer.OrdinalIgnoreCase);
        }

        public async Task<TableMeta> GetTableMetaAsync(DbConnection connection, string tableName)
        {
            if (string.IsNullOrEmpty(tableName))
            {
                throw new ArgumentNullException(nameof(tableName));
            }

            // 尝试从缓存获取
            if (_cache.TryGetValue(tableName, out var cachedMeta))
            {
                _logger.LogTrace($"从缓存获取表元数据: {tableName}");
                return cachedMeta;
            }

            // 从数据库加载
            _logger.LogDebug($"加载表元数据: {tableName}");
            var tableMeta = await _dialect.GetTableMetaAsync(connection, tableName);

            // 添加到缓存
            _cache.TryAdd(tableName, tableMeta);

            return tableMeta;
        }

        public async Task RefreshTableMetaAsync(DbConnection connection, string tableName)
        {
            _logger.LogInformation($"刷新表元数据: {tableName}");

            // 从数据库重新加载
            var tableMeta = await _dialect.GetTableMetaAsync(connection, tableName);

            // 更新缓存
            _cache.AddOrUpdate(tableName, tableMeta, (key, oldValue) => tableMeta);
        }

        public void Clear()
        {
            _logger.LogInformation("清除所有表元数据缓存");
            _cache.Clear();
        }

        public void Clear(string tableName)
        {
            _logger.LogInformation($"清除表元数据缓存: {tableName}");
            _cache.TryRemove(tableName, out _);
        }
    }
}
